import { ipcMain, dialog, app, BrowserWindow } from 'electron'
import { promises as fs } from 'fs'
import path from 'path'
import os from 'os'
import { logger } from './logger'
import { execFile } from 'child_process'

// 处理文件打开
ipcMain.handle('open-file', async () => {
  logger.info('IPC: open-file called')
  const result = await dialog.showOpenDialog({
    properties: ['openFile'],
    filters: [
      { name: 'Markdown Files', extensions: ['md', 'markdown'] },
      { name: 'All Files', extensions: ['*'] }
    ]
  })
  
  logger.info('Open file dialog result:', result)
  
  if (result.canceled) {
    return { canceled: true }
  }
  
  const filePath = result.filePaths[0]
  try {
    const content = await fs.readFile(filePath, 'utf-8')
    logger.info('File read successfully:', filePath)
    return { canceled: false, filePath, content }
  } catch (error: any) {
    logger.error('File read error:', error)
    return { canceled: true, error: error.message }
  }
})

// 处理文件保存
ipcMain.handle('save-file', async (_event, content, filePath) => {
  logger.info('IPC: save-file called', { content, filePath })
  try {
    await fs.writeFile(filePath, content, 'utf-8')
    logger.info('File saved successfully:', filePath)
    return { success: true }
  } catch (error: any) {
    logger.error('File save error:', error)
    return { success: false, error: error.message }
  }
})

// 处理文件另存为
ipcMain.handle('save-file-as', async (_event, content) => {
  logger.info('IPC: save-file-as called', { content })
  const result = await dialog.showSaveDialog({
    filters: [
      { name: 'Markdown Files', extensions: ['md'] },
      { name: 'All Files', extensions: ['*'] }
    ]
  })
  
  logger.info('Save file dialog result:', result)
  
  if (result.canceled) {
    return { canceled: true }
  }
  
  try {
    await fs.writeFile(result.filePath, content, 'utf-8')
    logger.info('File saved as successfully:', result.filePath)
    return { canceled: false, filePath: result.filePath }
  } catch (error: any) {
    logger.error('File save as error:', error)
    return { canceled: true, error: error.message }
  }
})

// 处理导出为HTML
ipcMain.handle('export-html', async (_event, content, title) => {
  logger.info('IPC: export-html called')
  const result = await dialog.showSaveDialog({
    filters: [
      { name: 'HTML Files', extensions: ['html'] },
      { name: 'All Files', extensions: ['*'] }
    ]
  })
  
  logger.info('Export HTML dialog result:', result)
  
  if (result.canceled) {
    return { canceled: true }
  }
  
  try {
    // 创建HTML内容
    const htmlContent = `
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>${title}</title>
    <style>
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
            line-height: 1.6;
            color: #333;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
        }
        h1, h2, h3, h4, h5, h6 {
            margin-top: 24px;
            margin-bottom: 16px;
            font-weight: 600;
            line-height: 1.25;
        }
        pre {
            background-color: #f6f8fa;
            border-radius: 6px;
            padding: 16px;
            overflow: auto;
        }
        code {
            font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
            font-size: 85%;
        }
        blockquote {
            margin: 0;
            padding: 0 1em;
            color: #6a737d;
            border-left: 0.25em solid #dfe2e5;
        }
    </style>
</head>
<body>
    ${content}
</body>
</html>
    `
    
    await fs.writeFile(result.filePath, htmlContent, 'utf-8')
    logger.info('HTML exported successfully:', result.filePath)
    return { canceled: false, filePath: result.filePath }
  } catch (error: any) {
    logger.error('HTML export error:', error)
    return { canceled: true, error: error.message }
  }
})

// 处理导出为PDF
ipcMain.handle('export-pdf', async (_event, content, title) => {
  logger.info('IPC: export-pdf called')
  try {
    const result = await dialog.showSaveDialog({
      filters: [
        { name: 'PDF Files', extensions: ['pdf'] },
        { name: 'All Files', extensions: ['*'] }
      ]
    })

    logger.info('Export PDF dialog result:', result)

    if (result.canceled || !result.filePath) {
      return { canceled: true }
    }

    // 创建用于渲染内容的隐藏窗口
    const win = new BrowserWindow({
      show: false,
      webPreferences: {
        sandbox: true
      }
    })

    const htmlContent = `
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>${title}</title>
    <style>
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
            line-height: 1.6;
            color: #333;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
        }
        h1, h2, h3, h4, h5, h6 {
            margin-top: 24px;
            margin-bottom: 16px;
            font-weight: 600;
            line-height: 1.25;
        }
        pre {
            background-color: #f6f8fa;
            border-radius: 6px;
            padding: 16px;
            overflow: auto;
        }
        code {
            font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
            font-size: 85%;
        }
        blockquote {
            margin: 0;
            padding: 0 1em;
            color: #6a737d;
            border-left: 0.25em solid #dfe2e5;
        }
        @page { margin: 12mm; }
    </style>
</head>
<body>
    ${content}
</body>
</html>
    `

    await win.loadURL('data:text/html;charset=utf-8,' + encodeURIComponent(htmlContent))

    const pdfBuffer = await win.webContents.printToPDF({
      printBackground: true,
      landscape: false
    })

    await fs.writeFile(result.filePath, pdfBuffer)
    win.destroy()

    logger.info('PDF exported successfully:', result.filePath)
    return { canceled: false, filePath: result.filePath }
  } catch (error: any) {
    logger.error('PDF export error:', error)
    return { canceled: true, error: error.message }
  }
})

// 获取应用版本
ipcMain.handle('get-app-version', () => {
  logger.info('IPC: get-app-version called')
  return app.getVersion()
})

// 主题切换
ipcMain.handle('toggle-theme', () => {
  logger.info('IPC: toggle-theme called')
  // 这里可以添加主题切换的逻辑
  return { success: true }
})

// 处理日志消息
ipcMain.handle('log-message', (_event, level, message, ...args) => {
  try {
    switch (String(level).toUpperCase()) {
      case 'DEBUG':
        logger.debug(message, ...args)
        break
      case 'INFO':
        logger.info(message, ...args)
        break
      case 'WARN':
        logger.warn(message, ...args)
        break
      case 'ERROR':
        logger.error(message, ...args)
        break
      default:
        logger.info(message, ...args)
    }
    return { success: true }
  } catch (error: any) {
    logger.error('Renderer log forwarding failed:', error)
    return { success: false, error: error?.message || String(error) }
  }
})

// 窗口控制
ipcMain.handle('minimize-window', (event) => {
  logger.info('IPC: minimize-window called')
  const win = BrowserWindow.fromWebContents(event.sender)
  if (win) {
    win.minimize()
  }
})

ipcMain.handle('toggle-maximize-window', (event) => {
  logger.info('IPC: toggle-maximize-window called')
  const win = BrowserWindow.fromWebContents(event.sender)
  if (win) {
    if (win.isMaximized()) {
      win.unmaximize()
    } else {
      win.maximize()
    }
  }
})

ipcMain.handle('close-window', async (event) => {
  logger.info('IPC: close-window called')
  const win = BrowserWindow.fromWebContents(event.sender)
  if (win) {
    // 触发窗口关闭事件，会被main.ts中的close事件处理器拦截
    win.close()
  }
})

// 处理保存图片文件
ipcMain.handle('save-image', async (_event, imageBuffer, fileName) => {
  logger.info('IPC: save-image called', { fileName })
  try {
    // 获取用户主目录
    const homeDir = os.homedir()
    const markdownGodDir = path.join(homeDir, 'markdowngod')
    
    // 创建年月子文件夹
    const now = new Date()
    const year = now.getFullYear().toString()
    const month = (now.getMonth() + 1).toString().padStart(2, '0')
    const yearMonthDir = path.join(markdownGodDir, year, month)
    
    // 确保目录存在
    await fs.mkdir(yearMonthDir, { recursive: true })
    
    // 生成唯一文件名（添加时间戳避免重名）
    const timestamp = Date.now()
    const fileExtension = path.extname(fileName) || '.png'
    const baseName = path.basename(fileName, fileExtension)
    const uniqueFileName = `${baseName}_${timestamp}${fileExtension}`
    const filePath = path.join(yearMonthDir, uniqueFileName)
    
    // 保存图片文件
    await fs.writeFile(filePath, imageBuffer)
    
    // 在Windows系统中，将反斜杠转换为正斜杠以避免URL编码问题
    const normalizedPath = filePath.replace(/\\/g, '/')
    
    logger.info('Image saved successfully:', filePath)
    return { success: true, filePath, absolutePath: normalizedPath }
  } catch (error: any) {
    logger.error('Image save error:', error)
    return { success: false, error: error.message }
  }
})

// 窗口最大化状态变化事件
app.on('browser-window-created', (event, window) => {
  window.on('maximize', () => {
    window.webContents.send('window-maximized', true)
  })
  
  window.on('unmaximize', () => {
    window.webContents.send('window-maximized', false)
  })
})

// 处理系统打印
ipcMain.handle('print', (event) => {
  logger.info('IPC: print called')
  try {
    const win = BrowserWindow.fromWebContents(event.sender)
    if (win) {
      // 调用系统打印对话框
      win.webContents.print({
        silent: false,
        printBackground: true,
        deviceName: ''
      })
      return { success: true }
    }
    return { success: false, error: 'No window found' }
  } catch (error: any) {
    logger.error('System print error:', error)
    return { success: false, error: error?.message || String(error) }
  }
})

// Windows 注册表键路径（当前用户）
const REG_BASE = 'HKCU\\Software\\MarkGodMarkdownEditor'

const regQuery = (key: string, valueName?: string): Promise<string | null> => {
  return new Promise((resolve) => {
    const args = ['query', key].concat(valueName ? ['/v', valueName] : [])
    logger.info('REG QUERY 调用', { key, valueName, args: ['reg.exe'].concat(args).join(' ') })
    execFile(
      'reg.exe',
      args,
      { windowsHide: true },
      (err, stdout) => {
        if (err) {
          logger.warn('REG QUERY 失败', { key, valueName, error: String(err) })
          resolve(null)
          return
        }
        const out = stdout?.toString() || ''
        logger.info('REG QUERY 输出', { key, valueName, output: out.trim() })
        resolve(out)
      }
    )
  })
}

const regAddValue = (key: string, valueName: string, data: string): Promise<boolean> => {
  return new Promise((resolve) => {
    const args = ['add', key, '/f', '/v', valueName, '/t', 'REG_SZ', '/d', data]
    logger.info('REG ADD 调用', { key, valueName, data, args: ['reg.exe'].concat(args).join(' ') })
    execFile(
      'reg.exe',
      args,
      { windowsHide: true },
      (err) => {
        if (err) {
          logger.warn('REG ADD 失败', { key, valueName, data, error: String(err) })
          resolve(false)
          return
        }
        logger.info('REG ADD 成功', { key, valueName, data })
        resolve(true)
      }
    )
  })
}

const readSettingsFromRegistry = async (): Promise<{ fontSize: number; editorWidth: number; theme: 'light' | 'dark' }> => {
  const defaults = { fontSize: 16, editorWidth: 50, theme: 'light' as 'light' | 'dark' }
  try {
    const themeOut = await regQuery(REG_BASE, 'theme')
    const fontOut = await regQuery(REG_BASE, 'fontSize')
    const widthOut = await regQuery(REG_BASE, 'editorWidth')

    logger.info('注册表读取原始输出', { themeOut: themeOut ? themeOut.trim() : null, fontOut: fontOut ? fontOut.trim() : null, widthOut: widthOut ? widthOut.trim() : null })

    const parseRegSz = (out: string | null): string | null => {
      if (!out) return null
      const m = out.match(/REG_SZ\s+([^\r\n]+)/)
      return m ? m[1].trim() : null
    }

    const t = parseRegSz(themeOut)
    const f = parseRegSz(fontOut)
    const w = parseRegSz(widthOut)

    logger.info('注册表解析后的设置', { theme: t, fontSize: f, editorWidth: w })

    return {
      fontSize: f ? parseInt(f, 10) || defaults.fontSize : defaults.fontSize,
      editorWidth: w ? parseInt(w, 10) || defaults.editorWidth : defaults.editorWidth,
      theme: (t === 'dark' || t === 'light') ? (t as 'light' | 'dark') : defaults.theme
    }
  } catch (e) {
    logger.warn('读取注册表设置失败，使用默认值', e)
    return defaults
  }
}

const writeSettingsToRegistry = async (s: { fontSize: number; editorWidth: number; theme: 'light' | 'dark' }) => {
  try {
    logger.info('开始写入注册表设置', s)
    const themeOk = await regAddValue(REG_BASE, 'theme', s.theme)
    logger.info('注册表写入 theme 结果', { success: themeOk })
    const fontOk = await regAddValue(REG_BASE, 'fontSize', String(s.fontSize))
    logger.info('注册表写入 fontSize 结果', { success: fontOk })
    const widthOk = await regAddValue(REG_BASE, 'editorWidth', String(s.editorWidth))
    logger.info('注册表写入 editorWidth 结果', { success: widthOk })

    const verify = await readSettingsFromRegistry()
    logger.info('注册表写入后验证读取', verify)

    return themeOk && fontOk && widthOk
  } catch (e) {
    logger.warn('写入注册表设置失败', e)
    return false
  }
}

// 获取设置（从注册表）
ipcMain.handle('get-settings', async () => {
  if (process.platform !== 'win32') {
    const defaults = { fontSize: 16, editorWidth: 50, theme: 'light' as 'light' | 'dark' }
    logger.info('非Windows平台返回默认设置', defaults)
    return defaults
  }
  const s = await readSettingsFromRegistry()
  logger.info('IPC: get-settings 返回', s)
  return s
})

// 保存设置（到注册表）
ipcMain.handle('save-settings', async (_event, settings: { fontSize: number; editorWidth: number; theme: 'light' | 'dark' }) => {
  try {
    logger.info('IPC: save-settings 收到', settings)
    if (process.platform !== 'win32') {
      logger.info('非Windows平台，跳过注册表写入，直接返回成功')
      return { success: true }
    }
    const ok = await writeSettingsToRegistry(settings)
    logger.info('IPC: save-settings 写入结果', { success: ok })
    return { success: ok }
  } catch (e: any) {
    logger.error('保存设置失败', e)
    return { success: false, error: e?.message || String(e) }
  }
  })